﻿using System;
using System.Reflection;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.Handler
{
    /// <summary>
    /// 验证方法中参数比某个数字大的处理类
    /// </summary>
    public class MoreThanHandler : ICallHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="MoreThanHandler"/> class.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="moreThanNumber">The more than number.</param>
        /// <param name="order">The order.</param>
        public MoreThanHandler(string parameterName, int moreThanNumber, int order)
        {
            ParameterName = parameterName;
            MoreThanNumber = moreThanNumber;
            Order = order;
        }

        /// <summary>
        /// 参数名
        /// </summary>
        public string ParameterName { get; set; }

        /// <summary>
        /// 必须大于的数字
        /// </summary>
        public int MoreThanNumber { get; set; }

        #region ICallHandler Members

        /// <summary>
        /// Order in which the handler will be executed
        /// </summary>
        /// <value></value>
        public int Order { get; set; }

        /// <summary>
        /// Implement this method to execute your handler processing.
        /// </summary>
        /// <param name="input">Inputs to the current call to the target.</param>
        /// <param name="getNext">Delegate to execute to get the next delegate in the handler
        /// chain.</param>
        /// <returns>Return value from the target.</returns>
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            for (int i = 0; i < input.Inputs.Count; i++)
            {
                object target = input.Inputs[i];
                if (target == null)
                {
                    ParameterInfo parameterInfo = input.Inputs.GetParameterInfo(i);
                    if (ParameterName == null)
                    {
                        var ex = new ArgumentNullException(parameterInfo.Name);
                        return input.CreateExceptionMethodReturn(ex);
                    }
                    else
                    {
                        if (parameterInfo.Name == ParameterName)
                        {
                            if (int.Parse(target.ToString()) < MoreThanNumber)
                            {
                                var ex =
                                    new ArgumentException(string.Format("参数{0}必须大于{1}", parameterInfo.Name,
                                                                        MoreThanNumber));
                                return input.CreateExceptionMethodReturn(ex);
                            }
                        }
                    }
                }
            }
            return getNext()(input, getNext);
        }

        #endregion
    }
}